package com.qf.config;


import com.qf.login.LoginFailureHandler;
import com.qf.login.LoginSuccessHandler;
import com.qf.login.MyRememberMeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.security.web.authentication.RememberMeServices;
import org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;

/**
 * @USER: Administrator
 * @DATE: 2025/8/30 下午7:06
 * @VERSION: 1.0.0
 */
@Configuration
@EnableWebSecurity // 启用 Spring Security
public class SecurityConfig {

    @Autowired
    private LoginFailureHandler loginFailureHandler;

    @Autowired
    private UserDetailsService userDetailsService;

    @Autowired
    private LoginSuccessHandler loginSuccessHandler;

    // 配置自定义 MyRememberMeService
    @Bean
    public RememberMeServices rememberMeServices() {
        // 签名密钥（生产环境建议从配置文件读取，确保安全）
        String rememberMeKey = "your-secure-key-123";
        // 创建自定义服务实例
        return new MyRememberMeService(rememberMeKey, userDetailsService);
    }

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
                // 添加验证码过滤器（在用户名密码过滤器之前执行）
                .addFilterBefore(captchaFilter(), UsernamePasswordAuthenticationFilter.class)

                // 授权配置
                .authorizeHttpRequests(authorize -> authorize
                        .requestMatchers(
                                new AntPathRequestMatcher("/css/**"),
                                new AntPathRequestMatcher("/js/**"),
                                new AntPathRequestMatcher("/login.jsp"),
                                new AntPathRequestMatcher("/captcha"))
                        .permitAll()
                        .anyRequest().authenticated()
                )
                // 登录配置
                .formLogin(formLogin -> formLogin
                        .loginPage("/login.jsp") // 登录页面地址
                        .loginProcessingUrl("/login") // 登录请求地址
                        .successHandler(loginSuccessHandler) // 自定义成功处理器，用于处理登录成功后的逻辑。不可与successForwardUrl同时使用
                        .failureHandler(loginFailureHandler) // 自定义失败处理器，用于处理登录失败后的逻辑。不可与failureForwardUrl同时使用
                )

                // 记住我配置
                .rememberMe(rememberMe -> rememberMe
                        .rememberMeServices(rememberMeServices())
                )

                // 退出配置
                .logout(logout -> logout
                        .logoutUrl("/logout") // 退出请求地址
                        .logoutSuccessUrl("/login?logout=true") // 退出成功后跳转的页面地址
                        .invalidateHttpSession(true) // 清除Session中的信息，防止用户在其他地方登录时，之前的Session仍然有效。默认为true
                        .clearAuthentication(true) // 清除SecurityContextHolder中的认证信息，防止用户在其他地方登录时，之前的Session仍然有效。默认为true
                        .deleteCookies("JSESSIONID") // 退出时删除指定Cookie（如SessionID）
                )

                .csrf().disable()
        ;

        return http.build();
    }

    /**
     * 配置自定义的密码加密器
     * @return
     */
    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

    /**
     * 验证码过滤器
     */
    @Bean
    public CaptchaFilter captchaFilter() {
        // 登录请求处理URL
        String loginProcessingUrl = "/login";
        // 验证码验证失败处理器：跳转到登录页并携带错误信息
        AuthenticationFailureHandler failureHandler = new SimpleUrlAuthenticationFailureHandler("/login?error=captcha");
        return new CaptchaFilter(loginProcessingUrl, failureHandler);
    }

    /**
     * 配置自定义的认证管理器
     * @param authConfig
     * @return
     * @throws Exception
     */
    @Bean
    public AuthenticationManager authenticationManager(AuthenticationConfiguration authConfig) throws Exception {
        return authConfig.getAuthenticationManager();
    }


}
